package paim.gh.controller;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.Vector;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JSpinner;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import paim.wingchun.controller.WC_Event;
import paim.wingchun.model.pojos.Pojo;

import paim.gh.model.modelos.TurnoModel;
import paim.gh.model.pojos.Horario;
import paim.gh.model.pojos.Turno;
import paim.gh.view.HorarioView;

/** @author paim 16/05/2011 */
public class HorarioController extends AbstractTabelaController<Horario, HorarioView> implements
                ChangeListener, MouseWheelListener, ActionListener {

    public HorarioController() {
        super();
    }

    @Override
    protected boolean antes_populaVisao() throws Exception {
        Vector<Pojo> lista = new Vector<Pojo>(TurnoModel.getInstance().list(getSessao()));
        ComboBoxModel<Pojo> model = new DefaultComboBoxModel<Pojo>(lista);
        getVisao().getJTurno().setModel(model);
        return super.antes_populaVisao();
    }

    @Override
    protected void apos_addListeners() {
        super.apos_addListeners();

        getVisao().getJTurno().addActionListener(this);

        getVisao().getjInicio().addChangeListener(this);
        getVisao().getjFim().addChangeListener(this);
        getVisao().getjInicio().addMouseWheelListener(this);
        getVisao().getjFim().addMouseWheelListener(this);

        /* adicionando listener somente na parte Texto do jspinner */
        ((JSpinner.DefaultEditor) getVisao().getjInicio().getEditor()).getTextField().addFocusListener(this);
        ((JSpinner.DefaultEditor) getVisao().getjFim().getEditor()).getTextField().addFocusListener(this);
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        /* verifica se nao esta parado */
        if ( !canDisparaEvento() )
            return;

        if ( !(e.getSource() instanceof JSpinner) )
            return;

        Object valorNovo = null;
        Object valorAntigo = null;

        JSpinner componente = (JSpinner) e.getSource();
        valorNovo = componente.getModel().getValue();

        Horario pojo = (Horario) getVisao().getObjetoReferencia();

        if ( getVisao().getjInicio().equals(componente) ) {
            valorAntigo = pojo.getInicio();
            if ( Objects.equals(valorAntigo, valorNovo) )
                return;
            /* altera no objeto */
            pojo.setInicio((Date) valorNovo);

            Format format = new SimpleDateFormat("HH:mm");
            String nome = format.format(valorNovo) + " - " + format.format(pojo.getFim());
            pojo.setNome(nome);
            pojo.setSigla(nome);
            /* altera na visao */
            getVisao().getJNome().setText(nome);
            getVisao().getJSigla().setText(nome);
            /* notifica mudanca */
            fire(new WC_Event(Eventos.ALTERANDO, pojo, valorAntigo, valorNovo, e, componente));

            /* se data de fim eh anterior ao inicio, ajuste e dispara evento automaticamnete */
            if ( pojo.getFim().compareTo(pojo.getInicio()) < 0 ) {
                getVisao().getjFim().getModel().setValue(pojo.getInicio());
            }
        }
        else if ( getVisao().getjFim().equals(componente) ) {
            valorAntigo = pojo.getFim();
            if ( Objects.equals(valorAntigo, valorNovo) )
                return;
            /* altera no objeto */
            pojo.setFim((Date) valorNovo);

            Format format = new SimpleDateFormat("HH:mm");
            String nome = format.format(pojo.getInicio()) + " - " + format.format(valorNovo);
            pojo.setNome(nome);
            pojo.setSigla(nome);
            /* altera na visao */
            getVisao().getJNome().setText(nome);
            getVisao().getJSigla().setText(nome);
            /* notifica mudanca */
            fire(new WC_Event(Eventos.ALTERANDO, pojo, valorAntigo, valorNovo, e, componente));
            /* se data de inicio eh posterior ao fim, ajuste e dispara evento automaticamnete */
            if ( pojo.getInicio().compareTo(pojo.getFim()) > 0 ) {
                getVisao().getjInicio().getModel().setValue(pojo.getFim());
            }
        }
        else
            /* se nao for outro componente cai fora */
            return;
    }

    @Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        /* verifica se nao esta parado */
        if ( !canDisparaEvento() )
            return;

        if ( !(e.getSource() instanceof JSpinner) )
            return;
        JSpinner componente = (JSpinner) e.getSource();

        if ( e.getWheelRotation() < 0 ) {
            if ( componente.getNextValue() != null )
                componente.setValue(componente.getNextValue());
        }
        else {
            if ( componente.getPreviousValue() != null )
                componente.setValue(componente.getPreviousValue());
        }

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if ( !canDisparaEvento() )
            return;

        if ( !(e.getSource() instanceof JComboBox) )
            return;

        Object valorNovo = null;
        Object valorAntigo = null;

        Horario pojo = (Horario) getVisao().getObjetoReferencia();

        JComboBox<?> componente = (JComboBox<?>) e.getSource();

        valorNovo = componente.getModel().getSelectedItem();

        if ( getVisao().getJTurno().equals(componente) ) {
            valorAntigo = pojo.getTurno();
            if ( Objects.equals(valorAntigo, valorNovo) )
                return;
            /* altera no objeto */
            pojo.setTurno((Turno) valorNovo);
            /* notifica mudanca */
            fire(new WC_Event(Eventos.ALTERANDO, pojo, valorAntigo, valorNovo, e, componente));
        }
        else
            /* se nao for outro componente cai fora */
            return;

        // TODO Auto-generated method stub

    }
}
